package com.ukefu.webim.web.handler.admin.multitenant;

import com.ukefu.core.UKDataContext;
import com.ukefu.util.Menu;
import com.ukefu.util.UKTools;
import com.ukefu.util.task.export.ExcelExporterProcess;
import com.ukefu.webim.service.acd.ServiceQuene;
import com.ukefu.webim.service.cache.CacheHelper;
import com.ukefu.webim.service.repository.*;
import com.ukefu.webim.service.sns.SnsAccountUtil;
import com.ukefu.webim.util.OnlineUserUtils;
import com.ukefu.webim.web.handler.Handler;
import com.ukefu.webim.web.handler.LoginController;
import com.ukefu.webim.web.model.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 	新版 - 多租户管理
 *
 */
@Controller
@RequestMapping("/admin/multitenant")
public class MultiTenantController extends Handler{
	
	@Autowired
	private TenantRepository tenantRes;//租户表
	
	@Autowired
	private UserRepository userRes;//用户表
	
	@Autowired
	private PbxHostRepository pbxHostRes ;//语音平台
	
	@Autowired
	private ExtentionRepository extentionRes;//分机表
	
	@Autowired
	private UserRoleRepository userRoleRes;

	@Autowired
	private PbxHostOrgiRelaRepository pbxHostOrgiRelaRepository;

	@Autowired
	private LoginController loginController;
	
	@Autowired
	private TenantTypeRepository tenantTypeRes;//租户分类表
	
	@Autowired
	private AgentServiceRepository agentServiceRes ;
	
	@Autowired
	private ServiceAiRepository serviceAiRes ;
	
	@Autowired
	private OrganRepository organRes ;
	
	@Autowired
	private MetadataRepository metadataRes ;

	/**
	 * 租户列表
	 * @param map
	 * @param request
	 * @return
	 */
	@RequestMapping("/index")
    @Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView index(final ModelMap map ,final HttpServletRequest request ,String msg,@Valid final String  tag,@Valid final String  category,@Valid final Boolean datastatus,@Valid final String  type) {
		map.addAttribute("tenantTypeList", tenantTypeRes.findByOrderBySortAsc());
		
		Page<Tenant> userList = tenantRes.findAll(new Specification<Tenant>() {
			@Override
			public Predicate toPredicate(Root<Tenant> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> list = new ArrayList<Predicate>();  
				Predicate p1 = cb.or(cb.like(root.get("tenantname").as(String.class), "%"+request.getParameter("q")+"%")
						,cb.like(root.get("tenantcode").as(String.class), "%"+request.getParameter("q")+"%")
						);
				if(!StringUtils.isBlank(request.getParameter("q"))) {
					list.add(cb.and(p1));
				}

				if(StringUtils.isNotBlank(tag)){
					list.add(cb.like(root.get("tag").as(String.class),"%" + tag + "%")) ;
				}
				if(StringUtils.isNotBlank(type)){
					list.add(cb.like(root.get("type").as(String.class),"%" + type + "%")) ;
					map.addAttribute("currtype", type);
				}
				if(StringUtils.isNotBlank(category)){
					list.add(cb.like(root.get("category").as(String.class),"%" + category + "%")) ;
				}
				if(datastatus != null){
					list.add(cb.equal(root.get("datastatus").as(Boolean.class), datastatus)) ;
				}

				Predicate[] p2 = new Predicate[list.size()];  
		        query.where(cb.and(list.toArray(p2)));
				return query.getRestriction();  
			}
		}, new PageRequest(super.getP(request), super.getPs(request), Sort.Direction.DESC,new String[]{"createtime"}));
		map.addAttribute("msg", msg);
		map.addAttribute("userList", userList);
		map.addAttribute("q", request.getParameter("q"));
		map.addAttribute("tag", tag);
		map.addAttribute("category", category);
		map.addAttribute("datastatus", datastatus);
		map.addAttribute("type", type);

		return request(super.createAppsTempletResponse("/admin/multitenant/index"));
    }
	/**
	 * 租户新增
	 * @param map
	 * @param request
	 * @return
	 */
	@RequestMapping("/add")
    @Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView add(ModelMap map , HttpServletRequest request,@Valid String type) {
		map.addAttribute("tenantcode",UKTools.getUUID());
		map.addAttribute("tenantTypeList", tenantTypeRes.findByOrderBySortAsc());
		map.addAttribute("currtype", type);
        return request(super.createRequestPageTempletResponse("/admin/multitenant/add"));
    }
	
	/**
	 * 租户新增 - 保存
	 * @param request
	 * @param tenant
	 * @return
	 */
	@RequestMapping("/add/save")
    @Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView save(HttpServletRequest request ,@Valid Tenant tenant,@Valid String currtype) {
		String msg = "" ;
		if(!StringUtils.isBlank(tenant.getTenantcode())){
			Tenant tenantData = tenantRes.findByTenantcode(tenant.getTenantcode());
			if(tenantData != null){
				msg = "admin_tenantcode_already_exist" ;
			}else{
				tenantRes.save(tenant);

				//授权模块
				Map<String , Boolean> modelMap = UKDataContext.orgiModel.get(tenant.getTenantcode());
				if(modelMap == null || modelMap.size() == 0){
					modelMap = new HashMap<>();
				}
				if(StringUtils.isNotBlank(tenant.getModels())) {
					modelMap.clear();
					String[] modelsArr = tenant.getModels().split(",");
					for(String model : modelsArr) {
						modelMap.put(model, true) ;
					}
				}else{
					modelMap = new HashMap<>();
				}

				UKDataContext.orgiModel.put(tenant.getTenantcode(),modelMap);

			}
		}
    	return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/index.html?msg="+msg+"&type="+currtype));
    }

	/**
	 * 租户编辑
	 * @param map
	 * @param request
	 * @return
	 */
	@RequestMapping("/edit")
	@Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
	public ModelAndView edit(ModelMap map , HttpServletRequest request,@Valid Tenant tenant,@Valid String currtype) {
		map.addAttribute("tenant" , tenantRes.findById(tenant.getId()));
		map.addAttribute("tenantTypeList", tenantTypeRes.findByOrderBySortAsc());
		map.addAttribute("currtype", currtype);
		return request(super.createRequestPageTempletResponse("/admin/multitenant/edit"));
	}

	/**
	 * 租户详情
	 * @param map
	 * @param request
	 * @return
	 */
	@RequestMapping("/detail")
	@Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
	public ModelAndView detail(ModelMap map , HttpServletRequest request,@Valid Tenant tenant) {
		map.addAttribute("tenant" , tenantRes.findById(tenant.getId()));
		map.addAttribute("tenantTypeList", tenantTypeRes.findByOrderBySortAsc());
		return request(super.createRequestPageTempletResponse("/admin/multitenant/detail"));
	}

	/**
	 * 租户新增 - 保存
	 * @param request
	 * @param tenant
	 * @return
	 */
	@RequestMapping("/edit/save")
	@Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
	public ModelAndView editsave(HttpServletRequest request ,@Valid Tenant tenant ,@Valid String currtype) {
		String msg = "" ;
		if(tenant != null){
			Tenant tenantData = tenantRes.findById(tenant.getId());
			if(tenantData != null){



				Tenant tenantData2 = tenantRes.findByTenantcode(tenant.getTenantcode());
				if(tenantData2 != null && !tenantData2.getId().equals(tenantData.getId())){
					msg = "admin_tenantcode_already_exist" ;
				}else{
					tenantData.setTenantcode(tenant.getTenantcode());
					tenantData.setProvince(tenant.getProvince());
					tenantData.setCity(tenant.getCity());
					tenantData.setArea(tenant.getArea());
					tenantData.setAddr(tenant.getAddr());
					tenantData.setMobile(tenant.getMobile());
					tenantData.setMail(tenant.getMail());
					tenantData.setQq(tenant.getQq());
					tenantData.setWechat(tenant.getWechat());
					tenantData.setAliwangwang(tenant.getAliwangwang());

					tenantData.setTag(tenant.getTag());
					tenantData.setDescription(tenant.getDescription());
					tenantData.setType(tenant.getType());
					tenantData.setCategory(tenant.getCategory());
					tenantData.setGrouping(tenant.getGrouping());
					tenantData.setScorestar(tenant.getScorestar());
					tenantData.setLevel(tenant.getLevel());
					tenantData.setMainbusiness(tenant.getMainbusiness());
					tenantData.setPcurl(tenant.getPcurl());
					tenantData.setH5url(tenant.getH5url());


					tenantData.setAgentnum(tenant.getAgentnum());
					tenantData.setCallcenteragentnum(tenant.getCallcenteragentnum());
					tenantData.setRobotagentnum(tenant.getRobotagentnum());

					tenantData.setModels(tenant.getModels());

					//授权模块
					Map<String , Boolean> modelMap = UKDataContext.orgiModel.get(tenantData.getTenantcode());
					if(modelMap == null || modelMap.size() == 0){
						modelMap = new HashMap<>();
					}
					if(StringUtils.isNotBlank(tenant.getModels())) {
						modelMap.clear();
						String[] modelsArr = tenant.getModels().split(",");
						for(String model : modelsArr) {
							modelMap.put(model, true) ;
						}
					}else{
						modelMap = new HashMap<>();
					}

					UKDataContext.orgiModel.put(tenantData.getTenantcode(),modelMap);

					tenantRes.save(tenantData);
				}
			}
		}
		return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/index.html?msg="+msg+"&type="+currtype));
	}

	
	@RequestMapping("/user/index")
    @Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView indexUer(ModelMap map , final HttpServletRequest request ,final String tenantcode) {
    	
		Tenant tenant = tenantRes.findByTenantcode(tenantcode);
		map.addAttribute("tenant", tenant);
		
		Page<User> page = userRes.findAll(new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> list = new ArrayList<Predicate>();  
				Predicate p = cb.and(cb.equal(root.get("orgi").as(String.class), tenantcode),cb.equal(root.get("datastatus").as(boolean.class), false));
				Predicate p1 = cb.or(cb.like(root.get("username").as(String.class), "%"+request.getParameter("q")+"%")
						,cb.like(root.get("uname").as(String.class), "%"+request.getParameter("q")+"%")
						,cb.like(root.get("email").as(String.class), "%"+request.getParameter("q")+"%")
						,cb.like(root.get("mobile").as(String.class), "%"+request.getParameter("q")+"%")
						);
				list.add(p);
				if(!StringUtils.isBlank(request.getParameter("q"))) {
					list.add(cb.and(p1));
				}
				Predicate[] p2 = new Predicate[list.size()];  
		        query.where(cb.and(list.toArray(p2)));
				return query.getRestriction();  
			}
		}, new PageRequest(super.getP(request), super.getPs(request), Sort.Direction.DESC,new String[] {"createtime"}));
    	map.addAttribute("userList", page);
    	map.addAttribute("tenantcode", tenantcode);
    	map.addAttribute("q", request.getParameter("q"));
        return request(super.createAdminTempletResponse("/admin/multitenant/user/index"));
    }
	
	@RequestMapping("/user/add")
    @Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView addUser(ModelMap map , HttpServletRequest request ,final String tenantcode) {
		map.addAttribute("tenantcode", tenantcode);
		if(UKDataContext.model.get("callcenter") != null) {
    		List<PbxHost> pbxHostList = pbxHostRes.findAll() ;
    		map.addAttribute("pbxHostList",pbxHostList);
    		if(pbxHostList!=null && !pbxHostList.isEmpty()) {
    			PbxHost pbxHost = pbxHostList.get(0) ;
    			map.addAttribute("pbxHost",pbxHost);
    			map.addAttribute("extentionList",extentionRes.findByHostidAndExtypeAndOrgi(pbxHost.getId() , UKDataContext.ExtentionType.LINE.toString(), super.getOrgi(request)));
    		}
    	}
        return request(super.createRequestPageTempletResponse("/admin/multitenant/user/add"));
    }
	
	@RequestMapping("/user/add/save")
	@Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView saveUser(HttpServletRequest request ,@Valid User user ,final String tenantcode) {
		String msg = "" ;
    	msg = validUser(user);
    	if(!StringUtils.isBlank(msg)){
    		return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/user/index.html?msg="+msg+"&tenantcode="+tenantcode));
    	}else if(!StringUtils.isBlank(user.getUsername()) && !StringUtils.isBlank(user.getPassword())){
    		if(request.getParameter("admin")!=null && super.getUser(request).isSuperuser()){
    			user.setUsertype("0");
    		}else{
    			user.setUsertype(null);
    		}
    		if(!StringUtils.isBlank(user.getPassword())){
    			user.setPassword(UKTools.md5(user.getPassword()));
    		}
    		
    		user.setOrgi(tenantcode);
    		user.setOrgid(tenantcode);
    		user.setTenant(true);
    		if(!StringUtils.isBlank(user.getExtid())) {
    			List<User> index = userRes.findByOrgiAndExtidAndDatastatus(super.getOrgi(request) , user.getExtid() , false) ;
    			Extention extention = extentionRes.findByIdAndOrgi(user.getExtid(), super.getOrgi(request)) ;
    			if(extention!=null && index.size() == 0) {
    				user.setExtno(extention.getExtention());
					userRes.save(user) ;
    				extention.setUserid(user.getId());
    				extention.setUsername(user.getUsername());
    				extention.setUname(user.getUname());
    				extentionRes.save(extention) ;
    				user.setExtno(extention.getExtention());
    			}else {
        			msg = "ext_exist" ;
        		}
    		}
    		userRes.save(user) ;
    		OnlineUserUtils.clean(super.getOrgi(request));
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/user/index.html?msg="+msg+"&tenantcode="+tenantcode));
    }
	private String validUser(User user) {
    	String msg = "";
    	User tempUser = userRes.findByUsernameAndDatastatus(user.getUsername(),false) ;
    	if(tempUser!=null) {
    		msg = "username_exist";
    		return msg;
    	}
    	tempUser = userRes.findByEmailAndDatastatus(user.getEmail(),false) ;
    	if(tempUser!=null) {
    		msg = "email_exist";
    		return msg;
    	}
    	tempUser = userRes.findByMobileAndDatastatus(user.getMobile(),false) ;
    	if(tempUser!=null) {
    		msg = "mobile_exist";
    		return msg;
    	}
    	return msg;
    }
	
    @RequestMapping("/user/edit")
	@Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView edit(ModelMap map ,HttpServletRequest request , @Valid String id, @Valid String p, @Valid String tenantcode) {
    	ModelAndView view = request(super.createRequestPageTempletResponse("/admin/multitenant/user/edit")) ;
    	view.addObject("userData", userRes.findByIdAndOrgi(id, tenantcode)) ;
    	if(UKDataContext.model.get("callcenter") != null) {
    		List<PbxHost> pbxHostList = pbxHostRes.findByOrgi(tenantcode);
    		map.addAttribute("pbxHostList",pbxHostList);
    		if(pbxHostList!=null && !pbxHostList.isEmpty()) {
    			PbxHost pbxHost = pbxHostList.get(0) ;
    			map.addAttribute("pbxHost",pbxHost);
    			map.addAttribute("extentionList",extentionRes.findByHostidAndExtypeAndOrgi(pbxHost.getId() , UKDataContext.ExtentionType.LINE.toString(), super.getOrgi(request)));
    		}
    		
    	}
    	map.addAttribute("p", p);
    	map.addAttribute("tenantcode", tenantcode);
        return view;
    }
    
    @RequestMapping("/user/update")
	@Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView update(HttpServletRequest request ,@Valid User user, @Valid String p, @Valid String tenantcode) {
    	User tempUser = userRes.findByIdAndOrgi(user.getId() , tenantcode) ;
    	String msg = null ;
    	if(tempUser != null && !StringUtils.isBlank(user.getUsername())){
    		msg = validUserUpdate(user,tempUser);
    		if(!StringUtils.isBlank(msg)){
    			return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/user/index.html?msg="+msg+"&tenantcode="+tenantcode));
    		}
    		tempUser.setUname(user.getUname());
    		tempUser.setUsername(user.getUsername());
    		tempUser.setEmail(user.getEmail());
    		tempUser.setMobile(user.getMobile());
    		
    		tempUser.setMaxuser(user.getMaxuser());
    		
    		if(!StringUtils.isBlank(tempUser.getExtid())) {
				Extention tempExtention = extentionRes.findByIdAndOrgi(tempUser.getExtid(), super.getOrgi(request)) ;
				if(tempExtention!=null) {
					tempExtention.setUserid(null);
					tempExtention.setUsername(null);
					tempExtention.setUname(null);
					extentionRes.save(tempExtention) ;
				}
			}
    		
    		if(!StringUtils.isBlank(user.getExtid())) {
    			List<User> index = userRes.findByOrgiAndExtidAndDatastatus(super.getOrgi(request) , user.getExtid() , false) ;
    			Extention extention = extentionRes.findByIdAndOrgi(user.getExtid(), super.getOrgi(request)) ;
    			if(extention!=null && (index.size() == 0 || index.get(0).getId().equals(tempUser.getId()))) {
    				tempUser.setExtno(extention.getExtention());
    				extention.setUserid(tempUser.getId());
    				extention.setUsername(tempUser.getUsername());
    				extention.setUname(tempUser.getUname());
    				
    				extentionRes.save(extention) ;
    				
    				tempUser.setBindext(user.isBindext());
    	    		tempUser.setHostid(user.getHostid());
    	    		tempUser.setExtid(user.getExtid());
    	    		tempUser.setExtno(extention.getExtention());
    			}else {
    				msg = "ext_exist" ;
    			}
    		}
    		
    		//切换成非坐席 判断是否坐席 以及 是否有对话
    		if(!user.isAgent()) {
    			AgentStatus agentStatus = (AgentStatus)CacheHelper.getAgentStatusCacheBean().getCacheObject(user.getId(), super.getOrgi(request));
    	    	if(!(agentStatus==null && ServiceQuene.getAgentUsers(user.getId(), super.getOrgi(request))==0)) {
    	    		return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/user/index.html?msg=t1"+"&tenantcode="+tenantcode));
    	    	}
    		}
    		tempUser.setAgent(user.isAgent());
    		
    		tempUser.setCallcenter(user.isCallcenter());
    		if(!StringUtils.isBlank(user.getPassword())){
    			tempUser.setPassword(UKTools.md5(user.getPassword()));
    		}
    		if(!tempUser.isSuperuser()) {
    			if(request.getParameter("admin")!=null && super.getUser(request).isSuperuser()){
    				tempUser.setUsertype("0");
    			}else{
    				tempUser.setUsertype(null);
    			}
    		}
    		if(tempUser.getCreatetime() == null){
    			tempUser.setCreatetime(new Date());
    		}
    		tempUser.setUpdatetime(new Date());
    		userRes.save(tempUser) ;
    		OnlineUserUtils.clean(super.getOrgi(request));
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/user/index.html"+(msg!=null?"?msg="+msg:"")+"&p="+p+"&tenantcode="+tenantcode));
    }
    private String validUserUpdate(User user,User oldUser) {
    	String msg = "";
    	User tempUser = userRes.findByUsernameAndDatastatus(user.getUsername(),false) ;
    	if(tempUser!=null&&!user.getUsername().equals(oldUser.getUsername())) {
    		msg = "username_exist";
    		return msg;
    	}
    	tempUser = userRes.findByEmailAndDatastatus(user.getEmail(),false) ;
    	if(tempUser!=null&&!user.getEmail().equals(oldUser.getEmail())) {
    		msg = "email_exist";
    		return msg;
    	}
    	tempUser = userRes.findByMobileAndDatastatus(user.getMobile(),false) ;
    	if(tempUser!=null&&!user.getMobile().equals(oldUser.getMobile())) {
    		msg = "mobile_exist";
    		return msg;
    	}
    	return msg;
    }
    
    @RequestMapping("/user/delete")
	@Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView deleteUser(HttpServletRequest request ,@Valid User user, @Valid String p, @Valid String tenantcode) {
    	String msg = "admin_user_delete" ;
    	if(user!=null){
	    	List<UserRole> userRole = userRoleRes.findByOrgiAndUser(tenantcode, user) ;
	    	userRoleRes.delete(userRole);	//删除用户的时候，同时删除用户对应的
	    	user = userRes.findByIdAndOrgi(user.getId(),tenantcode) ;
	    	user.setDatastatus(true);
	    	userRes.save(user) ;
	    	
	    	if(!StringUtils.isBlank(user.getExtid())) {
				Extention tempExtention = extentionRes.findByIdAndOrgi(user.getExtid(),tenantcode) ;
				if(tempExtention!=null) {
					tempExtention.setUserid(null);
					tempExtention.setUsername(null);
					tempExtention.setUname(null);
					extentionRes.save(tempExtention) ;
				}
			}
	    	
    	}else{
    		msg = "admin_user_not_exist" ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/user/index.html"+(msg!=null?"?msg="+msg:"")+"&p="+p+"&tenantcode="+tenantcode));
    }

	@RequestMapping("/datastatus")
	@Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
	public ModelAndView datastatus(HttpServletRequest request ,@Valid String id, @Valid Boolean datastatus, @Valid String p , @Valid String currtype) {
		Tenant tenant = tenantRes.findById(id);
		String msg = "";
		if(tenant != null && datastatus != null){
			tenant.setDatastatus(datastatus);
			tenantRes.save(tenant);
		}

		return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/index.html"+(msg!=null?"?msg="+msg:"")+"&p="+p+"&type="+currtype));
	}

    @RequestMapping("/delete")
	@Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView delete(HttpServletRequest request ,@Valid String id, @Valid String p) {
		String msg = deleteTenant(id);
    	return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/index.html"+(msg!=null?"?msg="+msg:"")+"&p="+p));
    }


    private String deleteTenant(String id){
		String msg = "admin_user_delete" ;
		Tenant tenant = tenantRes.findById(id);
		if(tenant != null){
			tenant.setDatastatus(true);
			List<User> userList = userRes.findByOrgi(tenant.getTenantcode());
			if(!userList.isEmpty()){
				for(User user : userList){
					if(user!=null){
						List<UserRole> userRole = userRoleRes.findByOrgiAndUser(tenant.getTenantcode(), user) ;
						userRoleRes.delete(userRole);	//删除用户的时候，同时删除用户对应的
						user = userRes.findByIdAndOrgi(user.getId(),tenant.getTenantcode()) ;
						user.setDatastatus(true);
						userRes.save(user) ;

						if(!StringUtils.isBlank(user.getExtid())) {
							Extention tempExtention = extentionRes.findByIdAndOrgi(user.getExtid(),tenant.getTenantcode()) ;
							if(tempExtention!=null) {
								tempExtention.setUserid(null);
								tempExtention.setUsername(null);
								tempExtention.setUname(null);
								extentionRes.save(tempExtention) ;
							}
						}

					}
				}
			}
			//tenantRes.delete(tenant);
			tenantRes.save(tenant);
		}
		return msg;
	}
	/**
	 * 新增租户 以及 管理员 以及分机号
	 * @return
	 */
	public Map<String,Object> addTenant(Map<String,Object> map) {
		String appId = (String)map.get("appId");
		//Tenant tenant = tenantRes.findByTenantcode(appId);
		String models = (String)map.get("models");

		Integer webagent = (Integer)map.get("webagent");
		Integer callcenteragent = (Integer)map.get("callcenteragent");
		Integer robotagent = (Integer)map.get("robotagent");

		Tenant tt = tenantRes.findByTenantcode(appId);
		Map<String,Object> resultMap = new HashMap<>();
		if(tt == null && !UKDataContext.SYSTEM_ORGI.equals(appId)){
			Tenant tenant = new Tenant();
			tenant.setTenantcode(appId);
			tenant.setTenantname(appId);
			tenant.setCreatetime(new Date());

			//授权模块
			tenant.setModels(models);

			//文本坐席 和 呼叫中心坐席
			tenant.setAgentnum(webagent);
			tenant.setCallcenteragentnum(callcenteragent);
			tenant.setRobotagentnum(robotagent);
			tenantRes.save(tenant);

			//新建管理员 TODO 判断用户名是否存在
			String adminpassword = (String)map.get("adminpassword");
			String mobile = (String)map.get("mobile");
			User userTemp = null;
			int i = 0;
			do{
				userTemp = userRes.findByUsernameAndDatastatus(mobile,false);
				if(userTemp != null){
					mobile = mobile + "_" + i;
					i++;
				}
			}while(userTemp != null);

			User user = new User();
			user.setUsername(mobile);
			user.setUname(mobile);
			user.setPassword(adminpassword);
			user.setUsertype("0");
			user.setSuperuser(false);

			user.setOrgi(tenant.getTenantcode());
			user.setOrgid(tenant.getTenantcode());

			userRes.save(user);

			//UKDataContext.model.put("cloud", true) ;
			//授权模块
			Map<String , Boolean> modelMap = UKDataContext.orgiModel.get(user.getOrgi());
			if(modelMap == null || modelMap.size() == 0){
				modelMap = new HashMap<>();
			}
			if(StringUtils.isNotBlank(models)) {
				modelMap.clear();
				String[] modelsArr = models.split(",");
				for(String model : modelsArr) {
					modelMap.put(model, true) ;
				}
			}else{
				modelMap = new HashMap<>();
			}

			UKDataContext.orgiModel.put(user.getOrgi(),modelMap);

			if(tenant.getCallcenteragentnum() > 0){
				PbxHost pbxHost = null;
				List<PbxHost> pbxHostList = pbxHostRes.findByDefaultpbx(true);
				if(pbxHostList.size() == 0 ){
					pbxHostList = pbxHostRes.findByOrgi(UKDataContext.SYSTEM_ORGI);
					if(pbxHostList.size() > 0){
						pbxHost = pbxHostList.get(0);
					}
				}else{
					pbxHost = pbxHostList.get(0);
				}
				PbxHostOrgiRela pbxHostOrgiRela = new PbxHostOrgiRela();
				List<PbxHostOrgiRela> pbxHostOrgiRelaList = pbxHostOrgiRelaRepository.findByPbxhostidAndOrgi(pbxHost.getId(),tenant.getTenantcode());
				if(pbxHostOrgiRelaList.size() > 0){
					pbxHostOrgiRela = pbxHostOrgiRelaList.get(0);
					pbxHostOrgiRela.setUpdatetime(new Date());
				}
				pbxHostOrgiRela.setPbxhostid(pbxHost.getId());
				pbxHostOrgiRela.setOrgi(tenant.getTenantcode());
				pbxHostOrgiRelaRepository.save(pbxHostOrgiRela);
				if(pbxHost != null){
					//找出未分配的直线分机
					List<Extention> extentionList = extentionRes.findByHostidAndExtypeAndAssignedOrderByExtentionAsc(pbxHost.getId(),UKDataContext.ExtentionType.LINE.toString(),false);
					if(extentionList.size() > 0){
						List<Extention> assignExtentionList = new ArrayList<>();
						int j = 0;

						for(Extention extention : extentionList){
							extention.setAssigned(true);
							extention.setOrgi(tenant.getTenantcode());
							if(tenant.getCallcenteragentnum() > j){
								assignExtentionList.add(extention);
								j++;
							}else{
								break;
							}
						}
						extentionRes.save(assignExtentionList);
					}
				}
			}
			resultMap.put("user" , user);
			resultMap.put("tenant",tenant);
		}
		return resultMap;

	}

	/**
	 * 停止租户 以及 管理员 以及分机号
	 * @return
	 */
	public Map<String,Object> stopTenant(Map<String,Object> map) {
		String appId = (String)map.get("appId");
		Tenant tt = tenantRes.findByTenantcode(appId);
		Map<String,Object> resultMap = new HashMap<>();
		if(tt != null){
			deleteTenant(tt.getId());
			resultMap.put("tenant",tt);
		}
		return resultMap;

	}

	@RequestMapping("/login")
	@ResponseBody
	public String tenantLogin(HttpServletRequest request  , HttpServletResponse response, @Valid String userid, @Valid String tenantcode){
		String msg = "";
		//超级管理员才有权限
		if(StringUtils.isNotBlank(userid) && super.isEnabletneantAndSuperUser(request)){
			User loginUser = userRes.findById(userid);

			if(loginUser!=null && !StringUtils.isBlank(loginUser.getId())){
				request.getSession().removeAttribute(UKDataContext.USER_SESSION_NAME) ;
				request.getSession().removeAttribute(UKDataContext.SUPERUSER_LOGIN_SESSION_NAME) ;
				request.getSession().invalidate();

				loginController.processLogin(request, response, null, loginUser, null) ;

				request.getSession(true).setAttribute(UKDataContext.SUPERUSER_LOGIN_SESSION_NAME , true) ;
			}else{
				msg = "login_error_user_not_exist";
			}
		}else{
			msg = "user_not_exsit_or_role_not_exist";
		}
		if(StringUtils.isNotBlank(msg)){
			//return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/user/index.html"+(msg!=null?"?msg="+msg:"")+"&tenantcode="+tenantcode));
			return "/admin/multitenant/user/index.html"+(msg!=null?"?msg="+msg:"")+"&tenantcode="+tenantcode;
		}else{
			//return request(super.createRequestPageTempletResponse("redirect:/"));
			return "/";
		}
	}
	
	@RequestMapping("/type/add")
    @Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView typeadd(ModelMap map , HttpServletRequest request) {
        return request(super.createRequestPageTempletResponse("/admin/multitenant/addtype"));
    }
	
	@RequestMapping("/type/save")
    @Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView typesave(ModelMap map , HttpServletRequest request,@Valid TenantType tenantType) {
		String msg = "";
		if(!StringUtils.isBlank(tenantType.getName())){
			TenantType temptype = tenantTypeRes.findByName(tenantType.getName());
			if(temptype != null){
				msg = "TenantType_EXIST";
			}else{
				tenantType.setCreater(super.getUser(request).getId());
				tenantType.setCreatetime(new Date());
				tenantTypeRes.save(tenantType);
			}
		}
        return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/index.html?msg="+msg));
    }
	
	@RequestMapping("/type/edit")
    @Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView typeedit(ModelMap map , HttpServletRequest request,@Valid String type) {
		if (!StringUtils.isBlank(type)) {
			TenantType tenantType = tenantTypeRes.findById(type);
			map.addAttribute("tenantType", tenantType);
		}
        return request(super.createRequestPageTempletResponse("/admin/multitenant/edittype"));
    }
	
	@RequestMapping("/type/update")
    @Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView typeupdate(ModelMap map , HttpServletRequest request,@Valid TenantType tenantType) {
		String msg = "";
		if(!StringUtils.isBlank(tenantType.getId())){
			TenantType tType = tenantTypeRes.findById(tenantType.getId());
			if(tType != null){
				if(!tType.getName().equals(tenantType.getName()) && tenantTypeRes.countByName(tenantType.getName())>0){
					msg = "TenantType_EXIST";
				}else{
					tType.setUpdatetime(new Date());
					tType.setName(tenantType.getName());
					tType.setSort(tenantType.getSort());
					tenantTypeRes.save(tType);
				}
			}
		}
        return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/index.html?msg="+msg+"&type="+tenantType.getId()));
    }
	
	@RequestMapping("/type/delete")
    @Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView typedelete(ModelMap map , HttpServletRequest request,@Valid String type) {
		String msg = "";
		if(!StringUtils.isBlank(type)){
			TenantType tType = tenantTypeRes.findById(type);
			if(tType != null){
				List<Tenant> tenantList = null;//tenantRes.findByType(type);
				if (tenantList != null && tenantList.size() > 0) {
					List<Tenant> saveList = new ArrayList<Tenant>();
					for(Tenant tenant : tenantList){
						tenant.setType(null);
						saveList.add(tenant);
					}
					if (saveList != null && saveList.size() > 0) {
						tenantRes.save(saveList);
					}
				}
				tenantTypeRes.delete(tType);
			}
		}
        return request(super.createRequestPageTempletResponse("redirect:/admin/multitenant/index.html?msg="+msg));
    }
	
	@RequestMapping("/servicehis")
	@Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
    public ModelAndView index(ModelMap map , HttpServletRequest request ,final String username,final String channel ,final String servicetype,final String skill,final String agent,final String servicetimetype,final String begin,final String end , final String sbegin,final String send,final @Valid String tenantid,@Valid String currtype) {
		if (!StringUtils.isBlank(tenantid)) {
			final Tenant tenant = tenantRes.findById(tenantid);
			if (tenant != null) {
				map.addAttribute("tenant", tenant);
				Page<AgentService> page = agentServiceRes.findAll(new Specification<AgentService>(){
					@Override
					public Predicate toPredicate(Root<AgentService> root, CriteriaQuery<?> query,CriteriaBuilder cb) {
						List<Predicate> list = new ArrayList<Predicate>();  
						if(!StringUtils.isBlank(username)) {
							list.add(cb.equal(root.get("username").as(String.class), username)) ;
						}
						
						list.add(cb.equal(root.get("orgi").as(String.class), tenant.getTenantcode())) ;
						
						if(!StringUtils.isBlank(channel)) {
							list.add(cb.equal(root.get("channel").as(String.class), channel)) ;
						}
						if(!StringUtils.isBlank(agent)) {
							list.add(cb.equal(root.get("agentno").as(String.class), agent)) ;
						}
						if(!StringUtils.isBlank(skill)) {
							list.add(cb.equal(root.get("agentskill").as(String.class), skill)) ;
						}
						try {
							if(!StringUtils.isBlank(begin) && begin.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")){
								list.add(cb.greaterThanOrEqualTo(root.get("logindate").as(Date.class), UKTools.dateFormate.parse(begin))) ;
							}
							if(!StringUtils.isBlank(end) && end.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")){
								list.add(cb.lessThanOrEqualTo(root.get("logindate").as(Date.class), UKTools.dateFormate.parse(end))) ;
							}
							
							if(!StringUtils.isBlank(sbegin) && sbegin.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")){
								list.add(cb.greaterThanOrEqualTo(root.get("servicetime").as(Date.class), UKTools.dateFormate.parse(sbegin))) ;
							}
							if(!StringUtils.isBlank(send) && send.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")){
								list.add(cb.lessThanOrEqualTo(root.get("servicetime").as(Date.class), UKTools.dateFormate.parse(send))) ;
							}
						} catch (ParseException e) {
							e.printStackTrace();
						}
						
						Predicate[] p = new Predicate[list.size()];  
						return cb.and(list.toArray(p));   
					}
				},new PageRequest(super.getP(request), super.getPs(request), Direction.DESC , "createtime")) ;
				for(AgentService service : page.getContent()) {
					if(!StringUtils.isBlank(service.getAppid())) {
						SNSAccount snsAccount = SnsAccountUtil.process(service.getAppid() ,service.getOrgi()) ;
						if(snsAccount!=null) {
							service.setSnsname(snsAccount.getName());
						}
					}
				}
				map.put("agentServiceList", page) ;
			}
		}
		map.put("username", username) ;
		map.put("channel", channel) ;
		map.put("servicetype", servicetype) ;
		map.put("servicetimetype", servicetimetype) ;
		map.put("agent", agent);
		map.put("skill", skill);
		map.put("begin", begin) ;
		map.put("end", end) ;
		map.put("sbegin", sbegin) ;
		map.put("send", send) ;
		map.put("organlist",organRes.findByOrgi(super.getOrgi(request)));
		map.put("userlist",userRes.findByOrgiAndDatastatus(super.getOrgi(request), false));
		List<ServiceAi> aiList = this.serviceAiRes.findByOrgi(super.getOrgi(request));
		map.addAttribute("aiList", aiList);
		map.addAttribute("tenantTypeList", tenantTypeRes.findByOrderBySortAsc());
		map.addAttribute("currtype", currtype);
        return request(super.createAppsTempletResponse("/admin/multitenant/history/index"));
    }
	
	@RequestMapping("/servicehis/expsearch")
	@Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
	public void expall(ModelMap map , HttpServletResponse response , HttpServletRequest request ,final String username,final String channel ,final String servicetype,final String skill,final String agent,final String servicetimetype,final String begin,final String end , final String sbegin,final String send,final @Valid String tenantid) throws IOException {
		if (!StringUtils.isBlank(tenantid)) {
			final Tenant tenant = tenantRes.findById(tenantid);
			if (tenant != null) {
				Page<AgentService> page = agentServiceRes.findAll(new Specification<AgentService>(){
					@Override
					public Predicate toPredicate(Root<AgentService> root, CriteriaQuery<?> query,CriteriaBuilder cb) {
						List<Predicate> list = new ArrayList<Predicate>();  
						if(!StringUtils.isBlank(username)) {
							list.add(cb.equal(root.get("username").as(String.class), username)) ;
						}
						
						list.add(cb.equal(root.get("orgi").as(String.class), tenant.getTenantcode())) ;
						
						if(!StringUtils.isBlank(channel)) {
							list.add(cb.equal(root.get("channel").as(String.class), channel)) ;
						}
						if(!StringUtils.isBlank(agent)) {
							list.add(cb.equal(root.get("agentno").as(String.class), agent)) ;
						}
						if(!StringUtils.isBlank(skill)) {
							list.add(cb.equal(root.get("skill").as(String.class), skill)) ;
						}
						try {
							if(!StringUtils.isBlank(begin) && begin.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")){
								list.add(cb.greaterThanOrEqualTo(root.get("logindate").as(Date.class), UKTools.dateFormate.parse(begin))) ;
							}
							if(!StringUtils.isBlank(end) && end.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")){
								list.add(cb.lessThanOrEqualTo(root.get("logindate").as(Date.class), UKTools.dateFormate.parse(end))) ;
							}
							
							if(!StringUtils.isBlank(sbegin) && sbegin.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")){
								list.add(cb.greaterThanOrEqualTo(root.get("servicetime").as(Date.class), UKTools.dateFormate.parse(sbegin))) ;
							}
							if(!StringUtils.isBlank(send) && send.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")){
								list.add(cb.lessThanOrEqualTo(root.get("servicetime").as(Date.class), UKTools.dateFormate.parse(send))) ;
							}
						} catch (ParseException e) {
							e.printStackTrace();
						}
						
						Predicate[] p = new Predicate[list.size()];  
					    return cb.and(list.toArray(p));   
					}
				},new PageRequest(super.getP(request),10000, Direction.DESC , "createtime")) ;

				MetadataTable table = metadataRes.findByTablenameIgnoreCase("uk_agentservice");
				List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
				for (AgentService agentService : page.getContent()) {
					values.add(UKTools.transBean2Map(agentService));
				}

				response.setHeader("content-disposition", "attachment;filename=UCKeFu-AgentService-History-"
						+ new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");

				ExcelExporterProcess excelProcess = new ExcelExporterProcess(values, table, response.getOutputStream());
				excelProcess.process();
			}
		}
		return;
	}
	
	@RequestMapping("/servicehis/expall")
	@Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
	public void expall(ModelMap map, HttpServletRequest request, HttpServletResponse response,final @Valid String tenantid) throws IOException {
		if (!StringUtils.isBlank(tenantid)) {
			final Tenant tenant = tenantRes.findById(tenantid);
			if (tenant != null) {
				Iterable<AgentService> agentServiceList = agentServiceRes.findByOrgi(tenant.getTenantcode(), new PageRequest(0, 10000));

				MetadataTable table = metadataRes.findByTablenameIgnoreCase("uk_agentservice");
				List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
				for (AgentService agentService : agentServiceList) {
					values.add(UKTools.transBean2Map(agentService));
				}

				response.setHeader("content-disposition", "attachment;filename=UCKeFu-AgentService-History-"
						+ new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");

				ExcelExporterProcess excelProcess = new ExcelExporterProcess(values, table, response.getOutputStream());
				excelProcess.process();
			}
		}
		return;
	}
	
	@RequestMapping("/servicehis/expids")
	@Menu(type = "admin" , subtype = "multitenant", admin = true , spadmin = true)
	public void expids(ModelMap map, HttpServletRequest request, HttpServletResponse response, @Valid String[] ids)
			throws IOException {
		if (ids != null && ids.length > 0) {
			Iterable<AgentService> agentServiceList = agentServiceRes.findAll(Arrays.asList(ids));
			MetadataTable table = metadataRes.findByTablenameIgnoreCase("uk_agentservice");
			List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
			for (AgentService agentService : agentServiceList) {
				values.add(UKTools.transBean2Map(agentService));
			}

			response.setHeader("content-disposition", "attachment;filename=UCKeFu-AgentService-History-"
					+ new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls");

			ExcelExporterProcess excelProcess = new ExcelExporterProcess(values, table, response.getOutputStream());
			excelProcess.process();
		}

		return;
	}
}
